package com.yueya.media.service;

import com.mongodb.gridfs.GridFSDBFile;
import com.yueya.im.common.util.PropertiesFileUtil;
import com.yueya.media.model.MediaDto;
import com.yueya.media.mongo.IGridFsDao;
import com.yueya.media.utils.FileUtils;
import com.yueya.im.common.util.SnowflakeIdWorker;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yueya
 */
public class MediaServiceImpl implements MediaService {
    @Autowired
    private IGridFsDao mongoDao;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private String bucket = PropertiesFileUtil.getInstance("mongodb").get("mongodb.bucket");

    @Override
    public List<MediaDto> findMediaList(String mainId) {
        List<GridFSDBFile> gfslist = mongoDao.findByMainId(mainId, bucket);
        List<MediaDto> medias = new ArrayList<>();
        for (GridFSDBFile dbfile : gfslist) {
            MediaDto media = new MediaDto();
            media.setId(dbfile.getId().toString());
            media.setExtenType(dbfile.getContentType());
            media.setMain_id(mainId);
            media.setName(dbfile.getFilename());
            media.setLength(dbfile.getLength());
            media.setMetadata(dbfile.getMetaData().toMap());
            medias.add(media);
        }
        return medias;
    }

    @Override
    public void deleteById(String id) {
        mongoDao.deleteById(id, bucket);
    }

    @Override
    public MediaDto getMedia(String id) {
        GridFSDBFile gridFSDBFile = mongoDao.findById(id, bucket);
        if (gridFSDBFile == null) {
            return null;
        }
        MediaDto dto = new MediaDto();
        dto.setName(gridFSDBFile.getFilename());
        dto.setLength(gridFSDBFile.getLength());
        dto.setId(gridFSDBFile.getId().toString());
        dto.setExtenType(gridFSDBFile.getContentType());
        if (gridFSDBFile.getMetaData() != null) {
            dto.setMetadata(gridFSDBFile.getMetaData().toMap());
        }
        return dto;
    }

    @Override
    public boolean addMeida(File f, String mainId) {
        boolean succ = false;
        String id = String.valueOf(SnowflakeIdWorker.generateId());
        String extendName = FileUtils.getFileExtension(f.getName());
        Map<String, String> metaData = new HashMap<>(1);
        metaData.put("main_id", mainId);
        try {
            mongoDao.save(id, new FileInputStream(f), f.getName(), extendName, metaData, bucket);
            succ = true;
        } catch (FileNotFoundException e) {
            logger.error("文件保存失败:", e);
            succ = false;
        }
        return succ;
    }

    @Override
    public String addNewMedia(String fileName, InputStream inputStream) {
        String id = String.valueOf(SnowflakeIdWorker.generateId());
        String extendName = FileUtils.getFileExtension(fileName);
        try {
            mongoDao.save(id, inputStream, fileName, extendName, null, bucket);
        } catch (Exception e) {
            logger.error("文件保存失败", e);
            return null;
        }
        return id;
    }

    @Override
    public boolean updateMeta(String id, Map<String, Object> exts) {
        return mongoDao.updateMeta(id, exts, bucket);
    }

    @Override
    public int saveMedias(String geonameId, String mediaIds) {
        if (StringUtils.isBlank(mediaIds) || StringUtils.isBlank(geonameId)) {
            return 0;
        }
        int count = 0;
        //mongo中关联地名的metadata键名
        String metaKey = "main_id";
        String[] mids = mediaIds.split(",");
        for (int i = 0; i < mids.length; i++) {
            Map<String, Object> exts = new HashedMap(1);
            exts.put(metaKey, geonameId);
            boolean succ = updateMeta(mids[i], exts);
            if (succ) {
                count++;
            }
        }
        return count;
    }

    @Override
    public boolean deleteByMainId(String mainId) {
        return mongoDao.deleteByMainId(mainId, bucket);
    }

    @Override
    public InputStream getInputStream(String id) {
        return mongoDao.getInputstream(id, bucket);
    }
}
